<?php

declare(strict_types=1);
/**
 * This file is part of habo_new_media.
 *
 * @link     https://www.berlen.cn/
 * @contact  tech@berlen.cn
 * @license  http://gitlab.rehou.cn/habo/habo_new_media/-/blob/master/README.md
 */
namespace app\service\fetch\ocean;

use app\enum\CommonEnum;
use app\enum\ConfigEnum;
use app\enum\OceanEnum;
use app\model\ClientAccountModel;
use app\model\mongo\MongoOeVideoModel;
use app\service\client\AccountService;
use app\service\fetch\MediaInterface;
use app\service\fetch\MediaService;
use app\service\ocean\AdvertiserService;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;

final class MongoEfficiencyVideoService extends MediaService implements MediaInterface
{
    /**
     * @var string 数据拉取key
     */
    protected const FETCH_KEY = ConfigEnum::CACHE_CONFIG[OceanEnum::LIST_CONFIG_LOCK_KEY]['mongo_efficiency_video'];

    protected static int $num = 100;

    /**
     * 更新低效视频素材.
     * @param string $advId 账户ID
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public static function getVideoList(string $advId = ''): bool
    {
        // 获取账户信息
        $obj = AccountService::getAccountModel(0, $advId);
        if (! $obj instanceof ClientAccountModel || ! $obj->getKey()) {
            return self::setError('账户数据不存在');
        }

        $page = 0;
        while (true) {
            $materialIds = self::_getGoodMaterialIds(intval($obj->getKey()), $page++);

            if (! $materialIds) {
                self::setError('无数据');
                break;
            }

            $res = self::_getList($advId, $materialIds);

            if ($res === false) {
                return false;
            }

            $lowMaterialIds = $res['data']['inefficient_material_ids'] ?? [];
            if (count($lowMaterialIds) == 0) {
                continue;
            }
            if (! self::_updateVideo(intval($obj->getKey()), $lowMaterialIds)) {
                return false;
            }
        }
        return true;
    }

    /**
     * 获取高效素材ids.
     * @param int $accountId 账户ID
     * @param int $page 页数
     */
    protected static function _getGoodMaterialIds(int $accountId = 0, int $page = 0): array
    {
        return (new MongoOeVideoModel())->where('account_id', $accountId)->where('is_good', MongoOeVideoModel::MATERIAL_GOOD)->limit($page * self::$num, self::$num)->column('material_id');
    }

    /**
     * 更新低效素材.
     * @param int $accountId 账户ID
     * @param array $materialIds 素材ids
     */
    private static function _updateVideo(int $accountId = 0, array $materialIds = []): bool
    {
        $res = (new MongoOeVideoModel())->where('account_id', $accountId)->whereIn('material_id', $materialIds)->update([
            'is_good' => MongoOeVideoModel::MATERIAL_BAD,
            'update_time' => time(),
        ]);

        if ($res <= 0) {
            return self::setError('保存信息出错!');
        }

        return true;
    }

    /**
     * 拉取信息.
     *
     * @return bool|mixed|string
     */
    private static function _getList(string $advId = '', array $materialIds = [])
    {
        $token = AccountService::getToken(CommonEnum::OE_MEDIA, $advId);
        if (! $token) {
            return self::setError('token获取失败');
        }
        $headers = [
            'Access-Token' => $token,
            'Content-Type' => 'application/json',
        ];
        $params = [
            'advertiser_id' => $advId,
            'material_ids' => $materialIds,
        ];

        return AdvertiserService::getEfficiencyVideoList($headers, $params);
    }
}
